<template>
  <div style="display:inline-grid;width: 100%">
    <div class="larry-tags-add-wrap">
      <div class="larry-tags-add-placeholder" v-if="tags.length === 0">{{placeholder}}</div>
      <div
        class="larry-tags-add"
        :key="item.tagUid"
        :style="{backgroundColor: bgc[item.tagBgNo]}"
        v-for="(item, index) in tags"
      >
        <span class="larry-tags-add-content">{{item[labelKey]}}</span>
        <span class="larry-tags-add-action">
          <span
            @click="handleUp(item.tagUid)"
            v-if="index!==0 && tags.length>1 && showSort && !disabled"
            style="margin-right: 5px"
          >&#8593;</span>
          <span
            @click="handleDown(item.tagUid)"
            v-if="index!==tags.length-1 && tags.length>1 && showSort && !disabled"
            style="margin-right: 5px"
          >&#8595;</span>
          <span v-if="!disabled" @click="handleDelete(item.tagUid)" style="margin-right: 5px">&times;</span>
        </span>
      </div>
    </div>
    <div v-if="showAdd && !disabled" style="margin-top:5px;">
      <Button type="primary" @click="showTable=true">添加</Button>
    </div>
    <Modal v-model="showTable" title="添加选项" fullscreen>
      <div v-if="showTable">
        <slot />
        <RemoteTable
          :namespace="namespace"
          :columns="columns"
          :selected="selectedValue"
          :needQueryParam="needQueryParam"
          :queryParam="queryParam"
          @onSelectionChange="handleTableSelectChange"
        />
      </div>
      <div slot="footer">
        <Button type="primary" @click="handleSubmitTableSelect">确定</Button>
      </div>
    </Modal>
  </div>
</template>

<script>
import Uuid from "uuid";
import compare from "@/utils/compare";
import RemoteTable from "@/components/RemoteTable";
import { Button, Modal, Message } from "view-design";
export default {
  name: "RemoteTableSelect",
  props: {
    value: {},
    /** 数据的唯一性key */
    primaryKey: {
      type: String,
      default: "id"
    },
    /** 是否禁用 */
    disabled: {
      type: Boolean,
      default: false
    },
    /** 没有数据的提示 */
    placeholder: {
      type: String,
      default: ""
    },
    /** 显示的属性名称，如果labelRender被传入，则该配置失效 */
    labelKey: {
      type: String,
      default: "name"
    },
    /** 构造label的函数 */
    labelRender: {
      type: Function
    },
    /** 点击添加时调用的函数 */
    handleAdd: {
      type: Function,
      default: function() {}
    },
    /** 栈模式，开启后，后添加的数据显示在前面 */
    stackMode: {
      type: Boolean,
      default: false
    },
    /** 是否显示排序 */
    showSort: {
      type: Boolean,
      default: false
    },
    /** vuex module名称 */
    namespace: String,
    /** 渲染列 */
    columns: Array,
    /** 是否需要参数才抓取数据 */
    needQueryParam: {
      type: Boolean,
      default: false,
      required: false
    },
    /** 最多可选 */
    limit: {
      type: Number,
      default: Number.MAX_VALUE,
      required: false
    },
    /** 查询参数 */
    queryParam: Object
  },
  components: { Button, Modal, RemoteTable },
  beforeMount() {
    this.tagsMate = this.initMetaData(this.$props.value);
  },
  model: {
    prop: "value",
    event: ["onChange"]
  },
  data() {
    return {
      /** tag元数据 */
      tagsMate: [],
      /** 背景颜色 */
      bgc: [
        "#e961b4",
        "#ed664b",
        "#7b6ac7",
        "#56abd1",
        "#f7af4c",
        "#fe5467",
        "#52c7bd",
        "#a479b7",
        "#cb81ce",
        "#5eabc5"
      ],
      /** 显示表格 */
      showTable: false,
      /** 自己发生的改变 */
      selfChange: false
    };
  },
  computed: {
    tags: function() {
      return this.tagsMate;
    },
    showAdd() {
      return this.tagsMate.length < this.$props.limit;
    },
    selectedValue() {
      let result = [];
      for (let i = 0; i < this.tagsMate.length; i++) {
        result.push(this.tagsMate[i].tagMetaData);
      }
      return result;
    }
  },
  watch: {
    value: function(newValue, oldValue) {
      if (!this.selfChange) {
        this.tagsMate = this.initMetaData(newValue);
      }
      this.selfChange = false;
    }
  },
  methods: {
    /** 初始化元数据 */
    initMetaData(metaData) {
      if (!metaData) {
        metaData = [];
      } else {
        if (metaData instanceof Function) {
          metaData = [];
        } else if (!(metaData instanceof Array)) {
          metaData = [metaData];
        }
      }
      let labelKey = this.labelKey;
      let tags = [];
      let tagsMate = metaData;
      for (let i = 0; i < tagsMate.length; i++) {
        let tag = null;
        if (tagsMate[i] instanceof Function) {
          continue;
        } else {
          tag = {
            tagUid: Uuid.v1(),
            tagBgNo: Math.ceil(Math.random() * 10) - 1,
            tagMetaData: tagsMate[i]
          };
          if (tagsMate[i] instanceof Object) {
            tag[labelKey] = tagsMate[i][labelKey];
          } else {
            tag[labelKey] = tagsMate[i];
          }
        }
        if (tag) {
          if (this.labelRender) {
            tag[labelKey] = this.labelRender(tagsMate[i]);
          }
          tags.push(tag);
        }
      }
      return tags;
    },
    /** 处理添加 */
    handleAddData(addValue) {
      let initData = this.initMetaData(addValue);
      let tagsMate = this.tagsMate;
      if (initData.length + tagsMate.length > this.$props.limit) {
        Message.error("所选数量超过限制");
        return;
      }
      let distanctData = [];
      for (let i = 0; i < initData.length; i++) {
        let exist = false;
        let a = initData[i].tagMetaData;
        for (let h = 0; h < tagsMate.length; h++) {
          let b = tagsMate[h].tagMetaData;
          if (this.primaryKey) {
            if (a[this.primaryKey] === b[this.primaryKey]) {
              exist = true;
              break;
            }
          } else if (compare(a, b)) {
            exist = true;
            break;
          }
        }
        if (!exist) {
          distanctData.push(initData[i]);
        }
      }
      /*** 如果是堆栈模式 */
      if (this.stackMode) {
        tagsMate = distanctData.concat(tagsMate);
      } else {
        tagsMate = tagsMate.concat(distanctData);
      }
      this.tagsMate = tagsMate;
      this.handleChange();
    },
    /** 处理删除 */
    handleDelete(tagUid) {
      let tagsMate = this.tagsMate;
      for (let i = 0; i < tagsMate.length; i++) {
        if (tagsMate[i].tagUid === tagUid) {
          tagsMate.splice(i, 1);
          this.tagsMate = tagsMate;
          break;
        }
      }
      this.handleChange();
    },
    /** 处理批量删除 */
    batchDelete(cancelSelect) {
      if (cancelSelect && cancelSelect.length > 0) {
        for (let h = 0; h < cancelSelect.length; h++) {
          let tagsMate = this.tagsMate;
          for (let i = 0; i < tagsMate.length; i++) {
            if (
              tagsMate[i].tagMetaData[this.primaryKey] ===
              cancelSelect[h][this.primaryKey]
            ) {
              tagsMate.splice(i, 1);
              this.tagsMate = tagsMate;
              break;
            }
          }
        }
        this.handleChange();
      }
    },
    handleUp(tagUid) {
      let tagsMate = this.tagsMate;
      for (let i = 0; i < tagsMate.length; i++) {
        if (tagsMate[i].tagUid === tagUid) {
          let temp = tagsMate[i];
          tagsMate[i] = tagsMate[i - 1];
          tagsMate[i - 1] = temp;
          this.tagsMate = tagsMate;
          break;
        }
      }
      this.handleChange();
    },
    handleDown(tagUid) {
      let tagsMate = this.tagsMate;
      for (let i = 0; i < tagsMate.length; i++) {
        if (tagsMate[i].tagUid === tagUid) {
          let temp = tagsMate[i];
          tagsMate[i] = tagsMate[i + 1];
          tagsMate[i + 1] = temp;
          this.tagsMate = tagsMate;
          break;
        }
      }
      this.handleChange();
    },
    handleChange() {
      let tagsMate = this.tagsMate;
      let result = [];
      for (let i = 0; i < tagsMate.length; i++) {
        result.push(tagsMate[i].tagMetaData);
      }
      this.selfChange = true;
      this.$emit("onChange", result);
    },
    handleTableSelectChange(selected, addSelect, cancelSelect) {
      this.tableSelected = selected;
      this.addSelect = addSelect;
      this.cancelSelect = cancelSelect;
    },
    handleSubmitTableSelect() {
      this.handleAddData(this.addSelect);
      this.batchDelete(this.cancelSelect);
      this.showTable = false;
    }
  }
};
</script>

<style lang="less">
.larry-tags-add-wrap {
  width: 100%;
  height: auto;
  outline: 0;
  padding: 2px 7px 2px 7px;
  min-height: 32px;
  height: auto !important;
  line-height: 1;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  box-sizing: border-box;
  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
  &::after {
    content: "";
    display: block;
    height: 0;
    clear: both;
  }
}
.larry-tags-add {
  position: relative;
  /*height: 28px;*/
  width: 100%;
  color: #fff;
  line-height: 28px;
  margin: 2px 0;
  padding: 0 22px 0 10px;
  border-radius: 4px;
  .larry-tags-add-content {
    line-height: 24px;
  }
  .larry-tags-add-action {
    width: 60px;
    height: 24px;
    text-align: right;
    cursor: pointer;
    position: absolute;
    right: 0;
  }
}
.larry-tags-add-placeholder {
  font-size: 13px;
  color: #b9bdd4;
  line-height: 28px;
}
</style>
